/**
 * 记录最大值
 * @param {Number} peak
 */
const memoPeak = (peak = 0) => {
  return (num = 0) => {
    if (num > peak) {
      peak = num;
    }
    return peak;
  };
};

/**
 * 移除属性
 * @param {Object} obj
 * @param {Array} props
 * @returns Object
 */
const omit = (obj, props) => {
  const _obj = { ...obj };
  props.forEach((prop) => {
    delete _obj[prop];
  });
  return _obj;
};

/**
 * 获得一个函数，执行该函数times(不含)次之后执行func
 * @param {Number} times
 * @param {Function} func
 * @returns {Function}
 */
const after = (times, func) => {
  if (times < 1) return func();
  return (...args) => {
    if (--times < 0) return func(...args);
  };
};

/**
 * 执行 times(含)次之后 不再执行 func
 * @param {Number} times
 * @param {Function} func
 * @returns {Function}
 */
const before = (times, func) => {
  return (...args) => {
    if (times-- > 0) func(...args);
  };
};

/**
 * 只取前n个参数
 * @param {Function} func
 * @param {Number} n
 * @returns {Function}
 */
function ary(func, n = func.length) {
  return (...args) => func(...args.slice(0, n));
}

/**
 * 科里化
 * @param {Function} func
 * @param {Number} len 限制参数长度
 * @returns {Function | any}
 */
function curry(func, len = func.length) {
  return (...args) => {
    if (len > args.length) return curry(func.bind(null, ...args));
    else return func(...args);
  };
}

/**
 * 单例
 * @param {Function} createInstance
 */
function singleton(createInstance) {
  let instance;
  return function (...args) {
    if (!instance) {
      instance = createInstance(...args);
    }
    return instance;
  };
}

export { after, ary, before, curry, memoPeak, omit, singleton };
